home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- TITLE CANJETDL - Print Screen Utility
-
- ;*** CANJETDL - Print Screen Utility
- ;
- ; CANJETDL is a print screen utility. It intercepts INT 5 from
- ; the BIOS (generated when <Print Screen> is struck), and prints
- ; the contents of the screen onto the PRN device.
- ;
- ; To execute:
- ;
- ; CANJETDL
- ;
- ; To activate:
- ;
- ; Press <Print Screen>
- ;
- ; OR, if using Mouse Systems' PC PAINT, execute CANJETDL before PC PAINT
- ; then, use the normal program procedures for printing a picture.
- ;
- ; Once CANJETDL has been executed, it remains permanently in RAM and
- ; does not need to be executed again.
- ;
- ;- Modified Aug 86 by SRN - Text dump to graphics.
- ; Modified again by Wayne D. Markel for IBM EGA
- ;- Canon PJ-1080A Inkjet graphics dump.
- ;- Code has been taken from various sources and been modified to suit.
- ;
- ; I wrote numerous versions of this program.
- ; This version was written specifically for use with IBM Drawing
- ; Assistant. It can only be invoked by using the PRINT SCREEN key,
- ; and therefore reads only the portion of the screen that contains the
- ; picture, not the border and icons.
- ;
- ; This version also rotates the picture 90 degrees and doubles up on
- ; the pixels in order to get a larger picture.
-
- ; NOTE: This is my first ever attempt at assembler programming so
- ; any comments for improvement would be appreciated.
- ; Wayne D. Markel
- ; 655 Carnathan Ct.
- ; Ft. Walton Beach, Florida 32548
- ; 904-862-5417
- ; Compuserve ID 71330,552
-
-
- FALSE = 0
- TRUE = NOT FALSE
-
- ; The next 2 switches should be set to TRUE and TRUE for:
- COLUMNS = 80 ; Characters/line
-
- page
-
-
-
- CODE SEGMENT BYTE PUBLIC 'CODE'
- ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
-
- ORG 100H
-
- ;* Entry point
- ;
-
- BEGIN:
- JMP NEAR PTR START
-
-
- ;* INT 5 handler
- ;
-
- INT_5:
- PUSH DS ; Save his data segment
- PUSH AX
-
- MOV CS:INT_SP,SP
- MOV CS:INT_SS,SS ; Save his stack
-
- MOV AX,CS
- MOV SS,AX ; Set local stack
- MOV SP,OFFSET INT_STACK
-
- STI ; Now allow interrupts to come in
-
- PUSH ES
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
-
- MOV DS,AX
- MOV ES,AX ; Set up my segments
-
- CALL CANJET
-
-
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP ES
-
- CLI ; INTs off while messing around
- MOV AX,CS:INT_SP
- MOV SP,AX
- MOV AX,CS:INT_SS ; Restore his stack
- MOV SS,AX
-
- POP AX
- POP DS
- IRET ; Back to BIOS
- INT_SS DW 0 ; Saved stack values
- INT_SP DW 0
-
- INT_CX DW 0 ; Current X location
- INT_CY DW 0 ; Current Y location
- MYCHR DW 0 ; Character at position
- MYLINE DB 82 DUP (?) ; Line buffer
- LINES DW 0 ; Number of lines valid on screen
- BLUE_BUFFER DB 80 DUP(?)
- GREEN_BUFFER DB 80 DUP(?)
- RED_BUFFER DB 80 DUP(?)
- DosVersMsg db "ATTR: Needs DOS 2.0 +$"
- LOAD_BUFFER DB ?
- ROW DW ?
- COLUMN DW ?
- NO_OF_BYTES EQU 50H
- DW 128 DUP (?)
- INT_STACK LABEL NEAR ; Internal stack
-
-
- CANJET PROC NEAR
- ;------------------------------------------------------------------------------
- ; PROCEDURE TO READ AN EGA MODE 16 SCREEN, ROTATE IT 90 DEGREES CLOCKWISE,
- ; DOUBLE THE DOT OUTPUT FROM 640X350 TO 1280X700 AND PRINT IT ON A CANON
- ; PJ1080A
- ;------------------------------------------------------------------------------
-
- ;This code for checking DOS version came from PC Magazine
-
- Mov AH, 30h ; Check for DOS Version
- Int 21h ; through DOS call
- Cmp AL, 2 ; See if it's 2.0 or above
- Jae DosVersOK ; If so, continue
-
- Mov DX, Offset DosVersMsg ; Error message
- ErrorExit:
- Mov AH, 9 ; Print String function call
- Int 21h ; Do it
- Int 20h ; And exit prematurely
-
- DosVersOK:
-
- ;-------------------------------------------------------------------------------
- ; READ A WINDOW, ONE DOT AT A TIME, RETURNING THE VALUE IN AL
- ;-------------------------------------------------------------------------------
-
- MOV COLUMN,92D ;INITIALIZE COLUMN COUNTER
-
- NEWCOLUMN:
-
- MOV LOAD_BUFFER,80H ;INITIALIZE THIS VARIABLE WHICH IS USED
- MOV ROW,337D ;SET ROW POINTER TO BOTTOM OF WINDOW
-
- ;------------------------------------------------------------------------------
- ; ZERO OUT BUFFERS AT BEGINNING OF EACH ROW
- ;------------------------------------------------------------------------------
- MOV CX,240D
-
- MOV BX,00 ;SET OFFSET POINTER TO ZERO
- ZERO: MOV [BLUE_BUFFER+BX],00 ;PUT ZERO IN BYTE OF RED_BUFFER
- INC BX
- LOOP ZERO
- ;------------------------------------------------------------------------------
- ; READ A DOT AT COLUMN=CX ROW=DX
- ; RETURN VALUE OF PIXEL IN AL
- ;------------------------------------------------------------------------------
- MOV BX,0 ;INITIALIZE POINTER FOR BUFFERS
- LINE: MOV CX,COLUMN ;SET CX TO CURRENT COLUMN
- MOV DX,ROW ;SET DX TO CURRENT ROW
- MOV AH,0DH ;READ DOT FUNCTION
- INT 10H
-
- MOV DH,LOAD_BUFFER ;SETUP DH TO TURN ON CORRECT BIT WHEN
- ; ORed WITH A BYTE IN ONE OF THE BUFFERS
- ;------------------------------------------------------------------------------
- ; In order to get a picture 8.25X15.0 inches on the CANON, it is necessary
- ; to write each pixel FOUR times. The EGA operates in 640X350 pixel
- ; mode. So the program will load the value of the pixel into a buffer
- ; TWICE and print each buffer TWICE. This will
- ; produce a picture on paper 1280 by 700 pixels in size.
- ;------------------------------------------------------------------------------
-
- CALL LOAD_BUFFERS
-
- CALL LOAD_BUFFERS
-
- ;------------------------------------------------------------------------------
- ; Ok, that doubled up on the pixels, now it's time to DEC the ROW
- ; counter to read the next pixel
- ;------------------------------------------------------------------------------
-
-
- DEC WORD PTR [ROW] ;DECREMENT THE ROW COUNTER
-
- ;------------------------------------------------------------------------------
- ; CHECK TO SEE IF AT TOP OF THE WINDOW
- ;------------------------------------------------------------------------------
-
- CMP WORD PTR [ROW],18D ;TEST IF ABOVE TOP OF WINDOW
- JGE LINE ;NO...READ ANOTHER DOT
-
-
- CALL OUTPUT_BUFFERS ;YES, OUTPUT ONE LINE TO CANONJET
-
- CALL OUTPUT_BUFFERS ;OUTPUT SECOND LINE
-
-
- INC WORD PTR [COLUMN] ;INCREMENT COLUMN NUMBER
-
- CMP WORD PTR [COLUMN],548D ;AT RIGHT EDGE OF WINDOW?
- JL NEWCOLUMN ;NO, READ ANOTHER COLUMN OF DOTS
-
- RET ;YES..HAVE READ ALL OF WINDOW, SO EXIT
- ;-------------------------------------------------------------------------------
- ; SUBROUTINE TO LOAD BUFFERS
- ;-------------------------------------------------------------------------------
-
- LOAD_BUFFERS PROC NEAR
-
- MOV AH,AL ;PUT THE VALUE FROM THE READ_DOT BIOS
- ; CALL INTO AH FOR FURTHER MANIPULATION
- SHR AH,1 ;PUSH THE LSB INTO THE BIT BUCKET
- ;------------------------------------------------------------------------------
- ; IF IT'S A "1", THEN TURN ON THE
- ; CORRESPONDING BIT IN THE CURRENT
- ; BYTE OF THE BLUE BUFFER
- ;------------------------------------------------------------------------------
-
- JNC GREEN ;IF IT'S A 0 CHECK THE GREEN BIT
- LOAD_BLUE_BUFFER:
- OR BYTE PTR [BLUE_BUFFER+BX],DH ;TURN ON A BIT IN BUFFER
-
- GREEN: SHR AH,1 ;SHIFT RIGHT ONE MORE TIME
- ; TO SEE IF THE 2 BIT IS ON
- ;IF YES, PUT A BIT IN THE GREEN BUFFER
- JNC RED ;IF NO, CHECK THE RED BIT
- LOAD_GREEN_BUFFER:
- OR BYTE PTR [GREEN_BUFFER+BX],DH
-
- RED: SHR AH,1 ;SHIFT ONE MORE TIME TO CHECK THE 4 BIT
-
- JNC END_LOAD_BUFFER ;IF NOT SET JUMP TO END_LOAD_BUFFER
- LOAD_RED_BUFFER:
- OR BYTE PTR[RED_BUFFER+BX],DH ;SINCE THE 4 BIT IS SET, LOAD...
- ; TO THE BUFFER
-
- END_LOAD_BUFFER:
- SHR DX,1
- MOV LOAD_BUFFER,DH ;SHR THE VARIABLE, "LOAD_BUFFER"
- CMP DH,00 ;HAVE WE READ 8 DOTS YET?
- JNZ SAME_BYTE ;NO, READ NEXT DOT
- MOV LOAD_BUFFER,80H ;RESET MSB OF LOAD_BUFFER
- MOV DH,LOAD_BUFFER ;SAME FOR DH
- ;-------------------------------------------------------------------------------
- ; AFTER STUFFING 8 DOTS INTO THE BUFFER, INCREMENT THE BUFFER OFFSET POINTER
- ;-------------------------------------------------------------------------------
- INC BX ;BUMP POINTER FOR BUFFERS
-
- SAME_BYTE:
-
- RET
-
-
- LOAD_BUFFERS ENDP
- ;------------------------------------------------------------------------------
-
- OUTPUT_BUFFERS PROC NEAR
-
- ;-------------------------------------------------------------------------------
- ; SET CANONJET TO GRAPHICS MODE...
- ; ...THEN OUTPUT ONE ROW OF DOTS TO THE CANONJET.
- ; NOTE: TWO ROWS OF DOTS MUST BE SENT BEFORE ANY PRINTER ACTION OCCURS
- ;
- ;-------------------------------------------------------------------------------
-
-
-
- MOV AH,5 ;SET DOS FUNCTION TO 5 FOR PRINT
- ;TER OUTPUT
- MOV DL,01BH ;SEND
- INT 21H ;ESCAPE CHARACTER
- MOV DL,058H ;THEN "X" CHARACTER
- INT 21H
- MOV DL,NO_OF_BYTES ;GET READY FOR 10 BYTES OF DATA
- INT 21H
-
- ;------------------------------------------------------------------------------
- ; OUTPUT (NO_OF_BYTES) FROM THE RED_BUFFER
- ;------------------------------------------------------------------------------
-
- MOV BX,0 ;SET OFFSET IN BUFFER TO ZERO
- RED_OUT: MOV DL,[RED_BUFFER+BX] ;PUT BYTE IN DL FOR OUTPUT TO
- ;PRINTER
- INT 21H ;DO IT.
- INC BX ;MOVE OVER TO NEXT BYTE IN
- ; BUFFER
- CMP BX,NO_OF_BYTES
- JL RED_OUT ;READ ANOTHER BYTE UNTIL 80
- ; HAVE BEEN READ.
-
- ;------------------------------------------------------------------------------
- ; OUTPUT (N0_OF_BYTES) FROM THE GREEN_BUFFER
- ;------------------------------------------------------------------------------
- MOV BX,0
- GREEN_OUT: MOV DL,[GREEN_BUFFER+BX]
- INT 21H
- INC BX
- CMP BX,NO_OF_BYTES
- JL GREEN_OUT
- ;------------------------------------------------------------------------------
- ; OUTPUT (NO_OF_BYTES) FROM THE BLUE_BUFFER
- ;------------------------------------------------------------------------------
- MOV BX,0
- BLUE_OUT: MOV DL,[BLUE_BUFFER+BX]
- INT 21H
- INC BX
- CMP BX,NO_OF_BYTES
- JL BLUE_OUT
- ;------------------------------------------------------------------------------
- ; ONE LINE OF DOTS HAVE BEEN OUTPUT TO THE CANONJET PRINT BUFFER
- ;------------------------------------------------------------------------------
- RET
- OUTPUT_BUFFERS ENDP
- ;-------------------------------------------------------------------------------
-
-
- RET ;NEAR RETURN TO DOS
- CANJET ENDP
-
-
- INT_END LABEL NEAR
-
- ;* Main entry point
- ;
-
- START:
- MOV SP,OFFSET INT_STACK ; Good place for it
- PUSH DS
-
- XOR AX,AX
- MOV DS,AX ; Clear DS
-
- MOV SI,5*4 ; SI points to interrupt
- CLI
-
- MOV WORD PTR [SI],OFFSET INT_5
- MOV WORD PTR [SI+2],CS ; Set my interrupt vector
-
- STI
- POP DS
-
- MOV DX,OFFSET INT_END ; LWA of resident portion
-
- ; MOV AH,31H ;FUNCTION FOR STAY RESIDENT
- ; MOV AL,1 ;RETURN CODE FOR COMMAND
- ; MOV DX,5D ;RESERVE 1.5K MEMORY
- ; INT 21H
- INT 27H
- CODE ENDS
- END BEGIN